﻿/* 
 * yaku
 * http://code.google.com/p/yaku/
 * 
 * Copyright 2011, Bryan McKelvey
 * Licensed under the MIT license
 * http://www.opensource.org/licenses/mit-license.php
 */

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Xml;

namespace yaku
{
    public partial class KanjiDic2
    {
        private List<Kanji> entries = new List<Kanji>();
        private const int maxResults = 50;

        public KanjiDic2()
        {
            if (File.Exists(Properties.Settings.Default.KanjiPath))
            {
                Load(Properties.Settings.Default.KanjiPath);
            }
        }

        public void Search(string kunyomi, string onyomi, int strokeCount, ref DataGrid resultsGrid)
        {
            // Use booleans to store whether we're going to search for certain parameters
            bool noKunyomi = (kunyomi == "");
            bool noOnyomi = (onyomi == "");
            bool noStrokeCount = (strokeCount == 0);

            // Search entries and return matches to results grid
            resultsGrid.ItemsSource = (from k in entries
                                       where (noKunyomi || Transliterator.Romanize(k.Kunyomi).Contains(kunyomi) || k.Kunyomi.Contains(kunyomi)) &&
                                             (noOnyomi || Transliterator.Romanize(k.Onyomi).Contains(onyomi) || k.Onyomi.Contains(onyomi)) &&
                                             (noStrokeCount || k.StrokeCount == strokeCount)
                                       orderby (k.Frequency == null ? 10000 : k.Frequency)
                                       select k).Take(maxResults);
        }

        /// <summary>
        /// Loads an XML file into the Edict object.
        /// </summary>
        /// <param name="fileName">The path to the XML file.</param>
        private void Load(string fileName)
        {
            Load(fileName, false);
        }

        /// <summary>
        /// Loads an XML file into the Edict object.
        /// </summary>
        /// <param name="fileName">The path to the XML file.</param>
        /// <param name="suppressStatus">Whether to suppress status updates. Defaults to false.</param>
        private void Load(string fileName, bool suppressStatus)
        {
            XmlTextReader reader = new XmlTextReader(fileName);
            entries.Clear();
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        switch (reader.Name)
                        {
                            case "character":
                                entries.Add(new Kanji());
                                break;
                            case "literal":
                                reader.Read();
                                entries.Last().Literal = reader.ReadContentAsString();
                                break;
                            case "rad_value":
                                reader.Read();
                                entries.Last().Radical = reader.ReadContentAsInt();
                                break;
                            case "grade":
                                reader.Read();
                                entries.Last().GradeLevel = reader.ReadContentAsInt();
                                break;
                            case "stroke_count":
                                reader.Read();
                                entries.Last().StrokeCount = reader.ReadContentAsInt();
                                break;
                            case "freq":
                                reader.Read();
                                entries.Last().Frequency = reader.ReadContentAsInt();
                                break;
                            case "jlpt":
                                reader.Read();
                                entries.Last().JLPT = reader.ReadContentAsInt();
                                break;
                            case "q_code":
                                if (reader.GetAttribute("qc_type") == "skip")
                                {
                                    reader.Read();
                                    string[] skipText = reader.ReadContentAsString().Split('-');
                                    if (skipText.Length == 3)
                                    {
                                        entries.Last().SkipCode = new int[]
                                        {
                                            int.Parse(skipText[0]), int.Parse(skipText[1]), int.Parse(skipText[2])
                                        };
                                    }
                                }
                                break;
                            case "reading":
                                switch (reader.GetAttribute("r_type"))
                                {
                                    case "ja_on":
                                        reader.Read();
                                        entries.Last().OnyomiList.Add(reader.ReadContentAsString().Replace(".", ""));
                                        break;
                                    case "ja_kun":
                                        reader.Read();
                                        entries.Last().KunyomiList.Add(reader.ReadContentAsString().Replace(".", ""));
                                        break;
                                }
                                break;
                            case "meaning":
                                if (!reader.HasAttributes)
                                {
                                    reader.Read();
                                    entries.Last().MeaningList.Add(reader.ReadContentAsString());
                                }
                                break;
                            case "nanori":
                                reader.Read();
                                entries.Last().NanoriList.Add(reader.ReadContentAsString());
                                break;
                        }
                        break;
                    /*
                    case XmlNodeType.EndElement:
                        entries.Last().Close();
                        break;
                     */
                }
            }
        }

        /// <summary>
        /// Manually loads an XML file into the dictionary database.
        /// </summary>
        public void ManualLoad()
        {
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog()
            {
                DefaultExt = "",
                Filter = "Dictionary files|*.*"
            };
            if (ofd.ShowDialog() == true)
            {
                Load(ofd.FileName);
                Properties.Settings.Default.DictPath = ofd.FileName;
            }
        }    
    }
}